//
//  BYNetworkHelper.m
//  BTCBOX
//
//  Created by biyunkeji on 2017/11/29.
//  Copyright © 2017年 jianfengChen. All rights reserved.
//

#import "NetworkHelper.h"
#import <CommonCrypto/CommonDigest.h>
#import "GiFHUD.h"
#import "config.h"
#import "AppDelegate.h"
#import "HudView.h"
#import "AppDelegate.h"
#import "ApiConfig.h"
#import "HostConfig.h"
#import "Reachability.h"
#import "UserDefaultsManager.h"
#import "CookieManager.h"
@implementation NetworkHelper

/**
 GET
 */
+ (NSURLSessionTask *)GET:(NSString *)URL
               parameters:(id)parameters
                  successResponseCodeCorrect:(HttpRequestSuccessResponseCodeCorrect)successResponseCodeCorrect successResponseCodeWrong:(HttpRequestSuccessResponseCodeWrong)successResponseCodeWrong
                  failure:(HttpRequestFailed)failure showError:(BOOL)error{
    NSLog(@"GET_URL = %@",URL);
    NSString *cacheKey = URL;
    URL = [NetworkHelper urlFreshWithOriginUrl:URL];
    if (parameters) {
        cacheKey = [URL stringByAppendingString:[self dictionaryConvertJsonString:parameters]];
    }
    [CookieManager syncCookie];
    AFHTTPSessionManager *manager = [self manager];
        return [manager GET:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [CookieManager saveCookie];
        [NetworkHelper validateResponseDataLegalityWithResponseData:responseObject successResponseCodeCorrect:successResponseCodeCorrect successResponseCodeWrong:successResponseCodeWrong showError:error];
        [NetworkHelper reSetTimeoutCount];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure ? failure(error) : nil;
        if (failure) {
            [NetworkHelper urlFailureWithError:error];
        };
    }];
}
/**
 POST
 */
+ (NSURLSessionTask *)POST:(NSString *)URL
                parameters:(id)parameters
                   successResponseCodeCorrect:(HttpRequestSuccessResponseCodeCorrect)successResponseCodeCorrect successResponseCodeWrong:(HttpRequestSuccessResponseCodeWrong)successResponseCodeWrong
                   failure:(HttpRequestFailed)failure showError:(BOOL )error
{
    NSLog(@"POST_URL = %@",URL);
	
	/**
	 *  无网络的时候执行
	 */
	Reachability *r = [Reachability reachabilityWithHostName:@"www.apple.com"];
	if (![r currentReachabilityStatus]) {
		[HudView showMsg:stringWithKey(@"Please check your network", nil) inView:nil];
		return nil;
	}
    NSString *cacheKey = URL;
    URL = [NetworkHelper urlFreshWithOriginUrl:URL];
    [CookieManager syncCookie];
    if (parameters) {
        cacheKey = [URL stringByAppendingString:[self dictionaryConvertJsonString:parameters]];
    }
    //进行签名，注册和登录暂不需要
    parameters = [NetworkHelper paramsAddSign:parameters andUrl:URL];
    AFHTTPSessionManager *manager = [self manager];
    [CookieManager syncCookie];
        return [manager POST:URL parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [CookieManager saveCookie];
        [NetworkHelper validateResponseDataLegalityWithResponseData:responseObject successResponseCodeCorrect:successResponseCodeCorrect successResponseCodeWrong:successResponseCodeWrong showError:error];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);
            [NetworkHelper urlFailureWithError:error];
        }
    }];
}
//验证后台返回数据的合法性
+ (void)validateResponseDataLegalityWithResponseData:(id)responseData successResponseCodeCorrect:(HttpRequestSuccessResponseCodeCorrect)successResponseCodeCorrect successResponseCodeWrong:(HttpRequestSuccessResponseCodeWrong)successResponseCodeWrong showError:(BOOL)error{
    //判断是否为空
    if (!responseData) {
        //网络错误
        if (error) {
            [[[UIAlertView alloc] initWithTitle:stringWithKey(@"Hint", nil) message: stringWithKey(@"alert_net_error", nil) delegate:nil cancelButtonTitle:stringWithKey(@"sure", nil) otherButtonTitles: nil] show];
        }
        return;
    }
    if(![responseData isKindOfClass:[NSDictionary class]]) {
        //不是字典时，后台返回什么数据取什么数据
        if (successResponseCodeCorrect) {
            successResponseCodeCorrect(responseData,@"");
        }
        return;
    }
    NSArray *keyArr = [responseData allKeys];
    NSString *RequestResponseCodeStr;
    if (![keyArr containsObject:RequestResponseStatus]) {
        //key既不包含code也不包含status，直接返回后台返回的数据
        if (successResponseCodeCorrect) {
            successResponseCodeCorrect(responseData,@"");
        }
        [NetworkHelper showAlerViewWithResponseDic:(NSDictionary *)responseData showError:error requestResponseCodeString:RequestResponseCodeStr];
        [NetworkHelper reSetTimeoutCount];
        return;
    }
    RequestResponseCodeStr = [NSString stringWithFormat:@"%@",[responseData objectForKey:RequestResponseStatus]];
    
    if ([RequestResponseCodeStr isEqualToString:RequestCorrectResponseCode]) {
        //返回码等于0
        if (successResponseCodeCorrect) {
            successResponseCodeCorrect(responseData,RequestResponseCodeStr);
        }
    }else{
        //返回码不等于0
        if (successResponseCodeWrong) {
            successResponseCodeWrong(responseData,RequestResponseCodeStr);
        }
    }
    [NetworkHelper showAlerViewWithResponseDic:(NSDictionary *)responseData showError:error requestResponseCodeString:RequestResponseCodeStr];
    [NetworkHelper reSetTimeoutCount];
}
//url操作，防止线上出bug，jspatch可进行热修复
+ (NSString *)urlFreshWithOriginUrl:(NSString *)url {
    return url;
}

+ (NSDictionary *)paramsAddSign:(NSDictionary *)parameters andUrl:(NSString *)URL {
    
    
    //进行签名
    
    return parameters;
    
}

//重置计数
+ (void)reSetTimeoutCount {
    
    NSUserDefaults *stnd = [NSUserDefaults standardUserDefaults];
    [stnd setInteger:0 forKey:@"timeout_count"];
    [stnd synchronize];
    
}

//在此处仅进行timeout错误码1001，来进行网络超时计数，达到20次，重新查看网络的连通性
+ (void)urlFailureWithError:(NSError *)err {
    
    if (err && (err.code==1001 || err.code == -1001 || err.code == -999)) {
        NSUserDefaults *stand = [NSUserDefaults standardUserDefaults];
        NSInteger count = [stand integerForKey:@"timeout_count"];
        NSUInteger time = [stand integerForKey:@"timeCurrent_error"];
        //判断时间间隔2分钟
        if (count >= 20 && (([NetworkHelper getNowTimeTimestamp] - time)>2*60)) {
            [NetworkHelper reReoladHostConfig];
            [stand setInteger:[NetworkHelper getNowTimeTimestamp] forKey:@"timeCurrent_error"];
        }
        count++;
        [stand setInteger:count forKey:@"timeout_count"];
        [stand synchronize];
    }
    
}

+ (NSInteger )getNowTimeTimestamp {
    
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    
    NSTimeInterval a=[dat timeIntervalSince1970];
    
    NSString*timeString = [NSString stringWithFormat:@"%0.f", a];//转为字符型
    
    return [timeString integerValue];
    
}

//重新请求
+ (void)reReoladHostConfig {
    
    [[HostConfig alloc] sharedHostAddress];
    [NetworkHelper reSetTimeoutCount];
    
}

/**
 错误的情况下提示错误信息

 @param dic 字典类型
 */
+ (void)showAlerViewWithResponseDic:(NSDictionary *)dic showError:(BOOL)error requestResponseCodeString:(NSString *)requestResponseCodeStr{
    
    if ([NetworkHelper jsPatchValueWithDic:dic]) {
        return;
    }
    if (![dic isKindOfClass:[NSDictionary class]]) {
        return;
    }
    /*此状态为登录失效，需要退出登录  1204表示需要登录
     *code=2202 sign错误
     */
    if (([requestResponseCodeStr intValue] == 1001) ||([requestResponseCodeStr intValue] == 1204)) {
        NSLog(@"退出登录的code是：%@", requestResponseCodeStr);
        AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
        [delegate.viewController LogutPopRootViewController];
        [NetworkHelper goLogoutView];
        return;
    }

    if (error) {
        [NetworkHelper showErrorWithDic:dic requestResponseCodeString:requestResponseCodeStr];
    }
}

+ (void)showErrorWithDic:(NSDictionary *)dic requestResponseCodeString:(NSString *)requestResponseCodeStr {
    //错误码不为0时的错误提示
    if ([requestResponseCodeStr intValue] == [RequestCorrectResponseCode intValue])
    {
        return;
    }
    if ([dic[RequestErrorMsg] isKindOfClass:[NSString class]] && [dic[RequestErrorMsg] length]) {
        [[[UIAlertView alloc] initWithTitle:stringWithKey(@"Hint",nil) message:dic[RequestErrorMsg] delegate:nil cancelButtonTitle:stringWithKey(@"sure",nil) otherButtonTitles:nil, nil] show];
        return;
    }
    if ([dic[RequestData] isKindOfClass:[NSString class]] && [dic[RequestData] length]) {
        [[[UIAlertView alloc] initWithTitle:stringWithKey(@"Hint",nil) message:dic[RequestData] delegate:nil cancelButtonTitle:stringWithKey(@"sure",nil) otherButtonTitles:nil, nil] show];
    }
}

//退出登录
+ (void)goLogoutView
{
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
    app.viewController.selectedIndex = 0;
}

//添加方法规避bug
+ (BOOL)jsPatchValueWithDic:(NSDictionary *)dic {
    
    return NO;
    
}

/**
 提示框
 */
/**
 提示框
 */
- (void)showAl {
    
    AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    if (!appDelegate.viewController) {
        NSLog(@"AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;");
        return;
    }
}
#pragma mark - 上传图片文件
+ (NSURLSessionTask *)uploadWithURL:(NSString *)URL
                         parameters:(NSDictionary *)parameters
                             images:(NSArray<UIImage *> *)images
                               name:(NSString *)name
                           fileName:(NSString *)fileName
                           mimeType:(NSString *)mimeType
                           progress:(HttpProgress)progress
                            successResponseCodeCorrect:(HttpRequestSuccessResponseCodeCorrect)successResponseCodeCorrect successResponseCodeWrong:(HttpRequestSuccessResponseCodeWrong)successResponseCodeWrong
                            failure:(HttpRequestFailed)failure
{
    AFHTTPSessionManager *manager = [self manager];
    [CookieManager syncAFSecurityPolicy];
    URL = [NetworkHelper urlFreshWithOriginUrl:URL];
    parameters = [NetworkHelper paramsAddSign:parameters andUrl:URL];
    
    return [manager POST:URL parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        //压缩-添加-上传图片
        [images enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {
            NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
            long index = idx;
            NSString *fileName1 = [NSString stringWithFormat:@"%@%ld.png", fileName, index];
            NSString *name1 = @"photo[]";
            [formData appendPartWithFileData:imageData name:name1 fileName:fileName1 mimeType:[NSString stringWithFormat:@"image/%@",mimeType?mimeType:@"jpeg"]];
        }];
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //上传进度
        progress ? progress(uploadProgress) : nil;
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [NetworkHelper validateResponseDataLegalityWithResponseData:responseObject successResponseCodeCorrect:successResponseCodeCorrect successResponseCodeWrong:successResponseCodeWrong showError:YES];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure ? failure(error) : nil;
    }];
}
#pragma mark - 下载文件
+ (NSURLSessionTask *)downloadWithURL:(NSString *)URL
                              fileDir:(NSString *)fileDir
                             progress:(HttpProgress)progress
                              success:(void(^)(NSString *))success
                              failure:(HttpRequestFailed)failure
{
    URL = [NetworkHelper urlFreshWithOriginUrl:URL];
    [CookieManager syncAFSecurityPolicy];
    AFHTTPSessionManager *manager = [self manager];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //下载进度
        progress ? progress(downloadProgress) : nil;
        //        NSLog(@"下载进度:%.2f%%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
        
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        //拼接缓存目录
        NSString *downloadDir = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileDir ? fileDir : @"Download"];
        //打开文件管理器
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        //创建Download目录
        [fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:nil];
        
        //拼接文件路径
        NSString *filePath = [downloadDir stringByAppendingPathComponent:response.suggestedFilename];
        
        //        NSLog(@"downloadDir = %@",downloadDir);
        
        //返回文件位置的URL路径
        return [NSURL fileURLWithPath:filePath];
        
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        success ? success(filePath.absoluteString /** NSURL->NSString*/) : nil;
        failure && error ? failure(error) : nil;
        
    }];
    
    //开始下载
    [downloadTask resume];
    
    return downloadTask;
}
+ (NetAPIClient *)manager {
    static NetAPIClient *manager = NULL;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [NetAPIClient sharedClient];
        manager.requestSerializer = [AFHTTPRequestSerializer serializer];
        [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        manager.requestSerializer.timeoutInterval = 20.0f;
        [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        manager.responseSerializer = [AFJSONResponseSerializer serializer];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain", nil];
        manager.requestSerializer.HTTPShouldHandleCookies = YES;
        
        
    });
    return manager;
}

+(void)timeoutInterval:(NSTimeInterval)timeInterval {
    AFHTTPSessionManager *manager = [self manager];
    manager.requestSerializer.timeoutInterval = timeInterval;
}

+ (void)cancelAllOperations {
    [[self manager].operationQueue cancelAllOperations];
}

+ (NSString *)dictionaryConvertJsonString:(id)parameter {
    NSData *data = [NSJSONSerialization dataWithJSONObject:parameter options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}
+ (BOOL )NotlocalNeed {
    
    return YES;
    
}

+ (NSString *)domainWithHost:(NSString *)url {
    
    if ([HOST containsString:@"http://"]) {
        return [url stringByReplacingOccurrencesOfString:@"http://" withString:@""];
    }
    
    return [url stringByReplacingOccurrencesOfString:@"https://" withString:@""];
    
}

@end
